package com.gitee.zhangchenyan.takin.sys.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import com.gitee.zhangchenyan.takin.common.result.Result;
import com.gitee.zhangchenyan.takin.common.result.ResultUtils;
import com.gitee.zhangchenyan.takin.common.utils.Tree;
import com.gitee.zhangchenyan.takin.sys.dto.*;
import com.gitee.zhangchenyan.takin.sys.entity.SysMenu;
import com.gitee.zhangchenyan.takin.sys.mapper.SysMenuMapper;
import com.gitee.zhangchenyan.takin.sys.mapper.SysRolesMenusMapper;
import com.gitee.zhangchenyan.takin.sys.page.SysMenuPageParam;
import com.gitee.zhangchenyan.takin.sys.service.ISysMenuService;
import com.gitee.zhangchenyan.takin.service.BaseServiceImpl;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zl
 * @since 2022-03-13
 */
@Service
public class SysMenuServiceImpl extends BaseServiceImpl<SysMenuMapper, SysMenu, SysMenuPageParam> implements ISysMenuService {

    @Autowired
    private SysRolesMenusMapper sysRolesMenusMapper;

    @Override
    public Wrapper<SysMenu> getPageWrapper(SysMenuPageParam pageParam) {
        return null;
    }

    @Override
    public Result del(SysCommonDelInput sysCommonDelInput) {
        LambdaQueryWrapper<SysMenu> queryWrapper = new QueryWrapper<SysMenu>().lambda();
        queryWrapper.isNotNull(SysMenu::getPid);
        queryWrapper.in(SysMenu::getPid, sysCommonDelInput.getId());
        List<SysMenu> sysMenuList = list(queryWrapper);
        if (sysMenuList != null && sysMenuList.size() > 0) {
            return ResultUtils.unknown("存在子级不允许删除！");
        }
        boolean isSuccess = removeByIds(sysCommonDelInput.getId());
        if (!isSuccess) {
            return ResultUtils.unknown("删除失败");
        }
        return ResultUtils.success();
    }

    @Override
    public void addMenu(SysMenuAddInput sysMenuAddInput) {
        SysMenu sysMenu = new SysMenu();
        if (StrUtil.isNotEmpty(sysMenuAddInput.getPid())) {
            sysMenu.setPid(Convert.toLong(sysMenuAddInput.getPid()));
        }
        if (StrUtil.isNotEmpty(sysMenuAddInput.getRedirect())) {
            sysMenu.setRedirect(sysMenuAddInput.getRedirect());
        }
        if (StrUtil.isNotEmpty(sysMenuAddInput.getIcon())) {
            sysMenu.setIcon(sysMenuAddInput.getIcon());
        }
        if (StrUtil.isNotEmpty(sysMenuAddInput.getPermission())) {
            sysMenu.setPermission(sysMenuAddInput.getPermission());
        }
        sysMenu.setSort(sysMenuAddInput.getSort());
        sysMenu.setType(sysMenuAddInput.getType());
        sysMenu.setTitle(sysMenuAddInput.getTitle());
        if (StrUtil.isNotEmpty(sysMenuAddInput.getPath())) {
            sysMenu.setPath(sysMenuAddInput.getPath());
        }
        if (StrUtil.isNotEmpty(sysMenuAddInput.getComponent())) {
            sysMenu.setComponent(sysMenuAddInput.getComponent());
        }
        if (StrUtil.isNotEmpty(sysMenuAddInput.getName())) {
            sysMenu.setName(sysMenuAddInput.getName());
        }
        if (sysMenuAddInput.getType() == 1) {
            sysMenu.setComponent("layout/routerView/parent");
        }
        sysMenu.setIsLink(sysMenuAddInput.getIsLink());
        sysMenu.setIsIframe(sysMenuAddInput.getIsIframe());
        if (sysMenuAddInput.getType() == 2 && sysMenuAddInput.getIsLink()) {
            sysMenu.setLink(sysMenuAddInput.getLink());
            if (sysMenuAddInput.getIsIframe()) {
                sysMenu.setComponent("layout/routerView/iframe");
            } else {
                sysMenu.setComponent("layout/routerView/link");
            }
        }
        sysMenu.setKeepAlive(sysMenuAddInput.getKeepAlive());
        sysMenu.setHide(sysMenuAddInput.getHide());
        sysMenu.setAffix(sysMenuAddInput.getAffix());
        save(sysMenu);
    }

    @Override
    public List<SysMenuRouteOut> getRoutes() {
        QueryWrapper<SysMenu> oneMenuQueryWrapper = new QueryWrapper<>();
        oneMenuQueryWrapper.lambda().isNull(SysMenu::getPid);
        List<SysMenu> oneMenus = list(oneMenuQueryWrapper);

        List<RolesByMenuIdDto> rolesByMenuIdDtoList = sysRolesMenusMapper.getAllRolesByMenuId();

        return getMenuToRoute(oneMenus, rolesByMenuIdDtoList);
    }

    @Override
    public List<SysMenuTreeOut> getMenu() {
        List<SysMenu> sysMenuList = list();
        List<SysMenuTreeOut> sysMenuTreeOutList = BeanUtil.copyToList(sysMenuList, SysMenuTreeOut.class);
        Tree<SysMenuTreeOut> tree = new Tree<>();
        return tree.getAll(sysMenuTreeOutList);
    }

    private List<SysMenuRouteOut> getMenuToRoute(List<SysMenu> sysMenus, List<RolesByMenuIdDto> rolesByMenuIdDtoList) {
        List<SysMenuRouteOut> menuRouteOuts = new ArrayList<>();
        for (SysMenu sysMenu : sysMenus) {
            SysMenuRouteOut menuRouteOut = new SysMenuRouteOut();
            menuRouteOut.setPath(sysMenu.getPath());
            menuRouteOut.setName(sysMenu.getName());
            menuRouteOut.setComponent(sysMenu.getComponent());
            menuRouteOut.setRedirect(sysMenu.getRedirect());
            menuRouteOut.setType(sysMenu.getType());
            SysMenuMetaOut menuMetaOut = new SysMenuMetaOut();
            menuMetaOut.setTitle(sysMenu.getTitle());
            menuMetaOut.setIsLink(sysMenu.getLink());
            menuMetaOut.setIsHide(sysMenu.getHide());
            menuMetaOut.setIsKeepAlive(sysMenu.getKeepAlive());
            menuMetaOut.setIsAffix(sysMenu.getAffix());
            menuMetaOut.setIsIframe(sysMenu.getIsIframe());
            menuMetaOut.setIcon(sysMenu.getIcon());
            List<String> ruleCodes = getRuleCodes(sysMenu.getId(), rolesByMenuIdDtoList);
            List<String> roles = new ArrayList<>(ruleCodes);
            menuMetaOut.setRoles(roles);
            menuRouteOut.setMeta(menuMetaOut);
            //目录继续循环
            if (sysMenu.getType() == 1) {
                List<SysMenuRouteOut> children = getByPid(sysMenu.getId(), rolesByMenuIdDtoList);
                menuRouteOut.setChildren(children);
            }
            menuRouteOuts.add(menuRouteOut);
        }
        return menuRouteOuts;
    }

    private List<SysMenuRouteOut> getByPid(long pid, List<RolesByMenuIdDto> rolesByMenuIdDtoList) {
        QueryWrapper<SysMenu> menuQueryWrapper = new QueryWrapper<>();
        menuQueryWrapper.lambda().eq(true, SysMenu::getPid, pid);
        List<SysMenu> menus = list(menuQueryWrapper);
        if (menus != null && menus.size() > 0) {
            return getMenuToRoute(menus, rolesByMenuIdDtoList);
        }
        return null;
    }

    private List<String> getRuleCodes(long menuId, List<RolesByMenuIdDto> rolesByMenuIdDtoList) {
        List<String> ruleCodes = new ArrayList<>();
        for (RolesByMenuIdDto rolesByMenuIdDto : rolesByMenuIdDtoList) {
            if (menuId == rolesByMenuIdDto.getMenuId()) {
                String[] temps = rolesByMenuIdDto.getRoleCode().split(",");
                ruleCodes.addAll(Arrays.asList(temps));
            }
        }
        return ruleCodes;
    }
}
